/**
	Pulsar engine. Core.
	Source file. Universal cross-platform synchronization primitives

	Copyright (C) 2013-2014 Dmitry Dolgov

	This program is free software; you can redistribute it and/or modify it under the terms of the
	GNU General Public License as published by the Free Software Foundation; either version 2 of
	the License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
	without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
	See the GNU General Public License for more details.
*/

#include <pulsar/pulsar.h>
#include <pulsar/src/pulsar_intr.h>

/**
	\param iniCoint initial semaphore value
	\param maxCoint max semaphore value
	Semaphote ctor
*/
pl::Semaphore::Semaphore(pl_uint32 iniCount, pl_uint32 maxCount, const pl_char* name/* = NULL*/) :
_pImpl(new(_reserved) SemaphoreImpl(iniCount, maxCount, name))
{
	return;
}

/**
	Semaphore dtor
*/
pl::Semaphore::~Semaphore()
{
	PL_ASSERTE(_pImpl != NULL, PL_T("Bad impl"));
	_pImpl->~SemaphoreImpl();
	_pImpl = NULL;
	return;
}

/**
	Invrease counter and allow other processes inside wait() to continue execution
*/
void pl::Semaphore::release()
{
	PL_ASSERTE(_pImpl != NULL, PL_T("Bad impl"));
	_pImpl->release();
	return;
}

/**
	\param timeMs - timeout to execute (0 - none, INFINITE)
	\return true, if sema was released
*/
bool pl::Semaphore::wait(pl_int32 timeMs)
{
	PL_ASSERTE(_pImpl != NULL, PL_T("Bad impl"));
	return _pImpl->wait(timeMs);
}

/**
	Crotocal section ctor
*/
pl::CriticalSection::CriticalSection(const pl_char* name/* = NULL*/) :
_pImpl(new (_reserved) CriticalSectionImpl(name))
{
	return;
}

/**
	Critical section dtor
*/
pl::CriticalSection::~CriticalSection()
{
	PL_ASSERTE(_pImpl != NULL, PL_T("Bad impl"));
	_pImpl->~CriticalSectionImpl();
	_pImpl = NULL;
	return;
}

/**
	Enteringto critical section
*/
void pl::CriticalSection::enter()
{
	PL_ASSERTE(_pImpl != NULL, PL_T("Bad impl"));
	_pImpl->enter();
	return;
}

/**
	Leaving the critical section
*/
void pl::CriticalSection::leave()
{
	PL_ASSERTE(_pImpl != NULL, PL_T("Bad impl"));
	_pImpl->leave();
	return;
}

/**
	Trying to enter to critical section
*/
bool pl::CriticalSection::tryEnter()
{
	PL_ASSERTE(_pImpl != NULL, PL_T("Bad impl"));
	return _pImpl->tryEnter();
}

//
// End of file 'pulsar_synchronize.cpp'
//
